package com.neutech.maplestory.entity;

import com.neutech.maplestory.client.MapleStoryClient;
import com.neutech.maplestory.constant.Constant;
import com.neutech.maplestory.util.ImageUtil;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;

/**
 * ·@author：冯。
 * ·@version：v.1.0。
 * ·@docroot：表示产生文档的根路径。
 * ·@param：方法的参数类型。
 * ·@return：方法的返回类型。
 */
public class Hero extends AbstractMapleStoryObject{
    public static Image[] imgs = new Image[100];
    static{
        for (int i = 0; i < 4; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_stand" + i);
        }
        for (int i = 4; i < 8; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_stand" + (i - 4));
        }
        for (int i = 8; i < 13; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_walk" + (i - 8));
        }
        for (int i = 13; i < 18; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_walk" + (i - 13));
        }
        imgs[18] = ImageUtil.getImage("hero_right_prone");
        imgs[19] = ImageUtil.getImage("hero_left_prone");
        imgs[20] = ImageUtil.getImage("hero_right_jump");
        imgs[21] = ImageUtil.getImage("hero_left_jump");
        for (int i = 22; i < 26; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_shoot" + (i - 22));
        }
        for (int i = 26; i < 30; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_shoot" + (i - 26));
        }
        // 添加向上爬绳子的图片
        imgs[30] = ImageUtil.getImage("hero_climb1");
        imgs[31] = ImageUtil.getImage("hero_climb2");
    }

   // public MapleStoryClient msc;
    public int HP;
    /**
     * 人物的最大血量
     */
    public int HP_MIX = 1000;

    public int MP;
    /**
     * 人物的最大魔法值
     */
    public int MP_MIX = 1000;
    /**
     * 基础攻击力
     */
    public int ATT;
    /**
     * 伤害值
     */
    public int hitValue;
    /**
     * EXP
     */
    public int EXP;
    /**
     * 等级
     */
    public int LV;

    public Random r = new Random();

    public Hero() {
    }
    public Hero(MapleStoryClient msc,int x,int y){
        this.msc = msc;
        this.x = x;
        this.y = y;
        this.speed = Constant.HERO_SPEED;
        this.width = imgs[0].getWidth(null);
        this.height = imgs[0].getHeight(null);
        this.dir = Direction.RIGHT;
        this.action = Action.STAND;

        this.HP = HP_MIX;
        this.MP = MP_MIX;

        this.ATT = 1000;
        this.EXP = 0;
        this.LV = 1;
        //System.out.println(hitValue);
    }

    /**
     * 计数器，一直增加
     */
    public int count;
    /**
     * 计算当前画第几张图
     */
    private int imgNum;
    @Override
    public void draw(Graphics g) {
        switch (dir){
            case RIGHT:
                switch (action){
                    case STAND:
                        //right stand
                        if (count++ % 5 == 0){
                            g.drawImage(imgs[imgNum++ % 4],x,y,null);
                        }
                        else{
                            g.drawImage(imgs[imgNum % 4],x,y,null);
                        }
                        break;
                    case WALK:
                        //right walk
                        if (count++ % 5 == 0){
                            g.drawImage(imgs[imgNum++ % 5 + 8],x,y,null);
                        }
                        else{
                            g.drawImage(imgs[imgNum % 5 + 8],x,y,null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[18],x,y+30,null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[20],x,y,null);
                        break;
                    case SHOOT:
                        //right shoot
                        if (count++ % 4 == 0){
                            g.drawImage(imgs[imgNum++ % 4 + 22],x,y,null);
                        }
                        else{
                            g.drawImage(imgs[imgNum % 4 + 22],x,y,null);
                        }
                        break;
                    case CLIMB:
                        // right climb
                        if (count++ % 2 == 0) {
                            g.drawImage(imgs[(imgNum++ % 2) + 30], x, y, null);
                        } else {
                            g.drawImage(imgs[(imgNum % 2) + 30], x, y, null);
                        }
                        break;
                    default:
                        break;
                }
                break;
            case LEFT:
                switch (action){
                    case STAND:
                        //left stand
                        if (count++ % 5 == 0){
                            g.drawImage(imgs[imgNum++ % 4 + 4],x,y,null);
                        }else{
                            g.drawImage(imgs[imgNum % 4 + 4],x,y,null);
                        }
                        break;
                    case WALK:
                        //left walk
                        if (count++ % 5 == 0){
                            g.drawImage(imgs[imgNum++ % 4 + 13],x,y,null);
                        }
                        else{
                            g.drawImage(imgs[imgNum % 4 + 13],x,y,null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[19],x,y+30,null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[21],x,y,null);
                        break;
                    case SHOOT:
                        //left shoot
                        if (count++ % 4 == 0){
                            g.drawImage(imgs[imgNum++ % 4 + 26],x,y,null);
                        }
                        else{
                            g.drawImage(imgs[imgNum % 4 + 26],x,y,null);
                        }
                        break;
                    case CLIMB:
                        // left climb
                        if (count++ % 2 == 0) {
                            g.drawImage(imgs[(imgNum++ % 2) + 30], x, y, null);
                        } else {
                            g.drawImage(imgs[(imgNum % 2) + 30], x, y, null);
                        }
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }

        move();
    }

    public boolean left,right,down,jump,shoot,pickUp,climb;

    @Override
    public void move() {
        if (left){
            x -= speed;
            this.action = Action.WALK;
        }
        if (right) {
            x += speed;
            this.action = Action.WALK;
        }
        if (jump){
            jump(msc.bases);
        }else if(climb(msc.ladder)){
            // 调用爬绳子的方法
            if(climb){
                this.y-=2;
            }

        }else{
            jumpDown(msc.bases);
        }
        if (shoot){
            shoot();
        }
        if (pickUp){
            pickUp(msc.items);
        }
        confirmStatus();
        OutOfBound();
    }

    /**
     *一次射击动作的count值
     */
    private int ShootCount;
    /**
     *射击的方法
     */
    private void shoot() {
        ShootCount++;
        if (ShootCount % 10 == 0){
            shoot = false;
            this.MP -= 5;

            Arrow arrow;
            if (dir == Direction.RIGHT){
                arrow = new Arrow(msc,x + width,y + height / 2 + 8,dir);
            }else{
                arrow = new Arrow(msc,x,y + height / 2 + 8,dir);
            }
            msc.arrows.add(arrow);
        }
    }

    private double v0 =Constant.INIT_JUMP_SPEED;
    private double vt;
    private double g = 9.8;
    private double delta_height;
    private double t = 0.7;
    /**
     * 跳跃的方法
     */
    private void jump(List<Base> bases) {
        //往上跳（竖直上抛）
        if (!drop){
            vt = v0 - g * t;
            delta_height = v0 * t;
            v0 = vt;
            y -= delta_height;
            //何时开始掉落
            if (vt <= 0){
                vt = 0;
                drop = true;
            }
        }else {
            jumpDown(bases);
        }

        /*//vt = v0 + gt    同时完成竖直上抛和自由落体
        vt = v0 - g * t;
        delta_height = v0 * t;
        v0 = vt;
        y -= delta_height;
        //自由落体的结束位置
        if(y >= 500){
            jump = false;
            v0 = Constant.INIT_JUMP_SPEED;
            vt = 0.0;
            y = 500;
        }*/
    }
    private boolean drop = true;
    public void jumpDown(List<Base> bases){
        //掉的过程  自由落体
        vt = v0 + g * t;
        delta_height = v0 * t;
        v0 = vt;
        y += delta_height;
        //什么时候停止自由落体
        for (int i = 0; i < bases.size(); i++) {
            Base base = bases.get(i);
            if (this.getRectangle().intersects(base.getRectangle()) &&
                this.y <= base.y - this.height + 40 +10){
                if (this.y >= base.y - this.height + 10){
                    this.y = base.y - this.height +10;
                    drop = false;
                    jump = false;
                    v0 = Constant.INIT_JUMP_SPEED;
                    vt = 0.0;
                    break;
                }
            }else{
                drop = true;
            }
        }
    }
    /**
     * 爬绳子的方法
     */
    private boolean climb(Base ladder){
        Rectangle re = ladder.getRectangle();
        //System.out.println("x:" + re.x);
        re.x = re.x + 27;
       // System.out.println("x:" + re.x);
        re.width = 10;
        //System.out.println("width:" + re.width);
        if (this.getRectangle().intersects(re)&&
                this.y >= ladder.y - this.height ){
            return  true;
        }
        //要是没碰到   爬为false
        climb = false;
        return false;
    }
   /* private boolean climb(List<Base> bases) {
        for (int i = 0; i < bases.size(); i++) {
            Base base = bases.get(i);
            if (this.getRectangle().intersects(base.getRectangle())&&
                    this.y >= base.y - this.height ){
                return  true;
            }
        }
        return  false;
    }*/

    /**
     * 根据当前人物的左右开关，确定人物的状态
     */
    private void confirmStatus(){
        if(left && !right){
            this.dir = Direction.LEFT;
            if(jump){
                this.action = Action.JUMP;
            }
        }else if(right && !left){
            this.dir = Direction.RIGHT;
            if(jump){
                this.action = Action.JUMP;
            }
        }else if (down){
            this.action = Action.PRONE;
        }else if (jump){
            this.action = Action.JUMP;
        }else if (shoot){
            this.action = Action.SHOOT;
        }else if (climb){
            this.action = Action.CLIMB;
        }
        else {
            //都按下或都不按下站立
            this.action = Action.STAND;
        }
    }

    /**
     * 按键的方法
     * @param e 键盘事件对象
     */
    public void keyPressed(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_A :
                left = true;
                break;
            case KeyEvent.VK_D :
                right = true;
                break;
            case KeyEvent.VK_S:
                down = true;
                break;
            case KeyEvent.VK_K: //跳跃
                jump = true;
                break;
            case KeyEvent.VK_J: //打
                shoot = true;
                break;
            case KeyEvent.VK_L: //拾取
                pickUp = true;
                break;
            case KeyEvent.VK_W: // 爬绳子
                climb= true;
                break;
        }
    }

    /**
     * 抬起键的方法
     * @param e 键盘事件对象
     */
    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()){
            case KeyEvent.VK_A :
                left = false;
                break;
            case KeyEvent.VK_D :
                right = false;
                break;
            case KeyEvent.VK_S:
                down = false;
                break;
            case KeyEvent.VK_L: //拾取
                pickUp = false;
                break;
            case KeyEvent.VK_W: // 爬绳子
                climb= false;
                break;
        }
    }
    /**
     * 人物出界
     */
    private void OutOfBound(){
        if (this.x <= 0){
            this.x = 0;
        }
        if (this.x >= Constant.GAME_WIDTH - this.width){
            this.x = Constant.GAME_WIDTH - this.width;
        }
        if (this.dir == Direction.RIGHT){
            if(this.x >= 517 - this.width && this.y >= 767 - this.height + 40){
                this.x = 517 - this.width;
            }
            if (this.x >= 627 - this.width && this.y >= 698 - this.height + 40 &&
                    this.x <= 1510 - this.width){
                this.x = 627 - this.width;
            }
        }
        if (this.dir == Direction.LEFT){
            if (this.x <= 1510 && this.y >= 698 - this.height + 40 && this.x >= 627 - this.width){
                this.x = 1510;
            }
        }
    }

    /**
     * 英雄拾取道具的方法
     * @param item  被拾取的道具对象
     * @return 是否拾取到
     */
    private boolean pickUp(Item item){
        if(item.live && this.getRectangle().intersects(item.getRectangle())){
            item.live = false;
            //存放之前和道具包里的每一个判断
            for (int i = 0; i < msc.itemPackage.items.size(); i++) {
                Item pItem = msc.itemPackage.items.get(i);
                if (pItem.type == item.type){
                    //如有相同的数量+1
                    pItem.qty += 1;
                    return false;
                }
            }
            //业务  放入道具包
            msc.itemPackage.items.add(item);
           /*switch (item.type){
               case 0:
                   this.HP += 50;
                   break;
               case 1:
                   this.HP += 100;
                   break;
               case 2:
                   this.HP += 300;
                   break;
               case 3:
                   this.MP += 100;
                   break;
               default:
                   break;
           }
           if (HP > HP_MIX){
               HP = HP_MIX;
           }
           if (MP > MP_MIX){
               MP = MP_MIX;
           }*/
            return true;
        }
        return false;
    }

    /**
     * 英雄拾取一容器的道具
     * @param items  道具容器
     * @return 是否拾取到
     */

    public boolean pickUp(List<Item> items){
        //System.out.println("0000000000");
        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);
            if (pickUp(item)){
                return true;
            }
        }
        return false;
    }


}


